home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / postman.zip / POSTMAN.C < prev    next >
C/C++ Source or Header  |  1991-05-01  |  20KB  |  605 lines

  1. //
  2. //         Postman -- Windows PostMessage Utility
  3. //                    Chiverton Graphics, Inc., 1991
  4. //
  5. //
  6. #include <windows.h>
  7. #include <ctype.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <stdlib.h>
  11. #include "postman1.h"
  12. #include "dlgdefs.h"
  13.  
  14.  
  15.  
  16.  
  17. /* proc addresses needed for subclassing */
  18. static FARPROC lpprocFilterHexNumber,
  19.                lpEditControlProc;
  20.  
  21. static WORD wEditID[6] = {
  22.                          IDD_EDIT_HWND,
  23.                          IDD_EDIT_WMSG,
  24.                          IDD_EDIT_WPARAM,
  25.                          IDD_EDIT_LPARAM,
  26.                          IDD_EDIT_HIWORD,
  27.                          IDD_EDIT_LOWORD
  28.                          };
  29.  
  30. static WORD wFile = IDD_RB_WM;
  31.  
  32. HANDLE hInstance ;
  33.  
  34. static void show_lparam_controls (HWND hDlg, BOOL bHiLo);
  35. static void check_control_enable (HWND hDlg, int idEdit, int idButton, WORD message);
  36. static void fill_hwnd_combobox   (HWND hDlg);
  37. static void fill_wmsg_combobox   (HWND hDlg);
  38.  
  39. static void combobox_DrawEntireItem (LPDRAWITEMSTRUCT lp);
  40. static void combobox_DrawSelection  (LPDRAWITEMSTRUCT lp);
  41. static void combobox_DrawFocus      (LPDRAWITEMSTRUCT lp);
  42.  
  43. BOOL FAR PASCAL DialogWndProc     (HWND hDlg, unsigned message, WORD wParam, LONG lParam);
  44. BOOL FAR PASCAL AboutDialogWndProc(HWND hDlg, unsigned message, WORD wParam, LONG lParam);
  45. long FAR PASCAL filter_hex_number (HWND hWnd, unsigned message, WORD wParam, LONG lParam);
  46.  
  47.  
  48.  
  49.  
  50. int PASCAL WinMain (HANDLE hInst, HANDLE hPrevInst, LPSTR lpszCmdLine, int nCmdShow )
  51.      {
  52.      FARPROC lpProc;
  53.  
  54.      hInstance = hInst;
  55.  
  56.      lpProc = MakeProcInstance ((FARPROC) DialogWndProc, hInstance);
  57.      DialogBox (hInstance, MAKEINTRESOURCE (IDD_DIALOG), NULL, lpProc);
  58.      FreeProcInstance (lpProc);
  59.  
  60.      return 0L;
  61.      }
  62.  
  63.  
  64.  
  65. BOOL FAR PASCAL DialogWndProc (HWND hDlg, unsigned message, WORD wParam, LONG lParam)
  66.    {
  67.    int  i;
  68.    LONG lResult;
  69.    static BOOL bHiLo = FALSE;     // use lParam initially
  70.  
  71.    switch (message)
  72.    {
  73.    case WM_INITDIALOG:
  74.  
  75.         // Add the About Postman... dlgbox to the system menu
  76.         {
  77.         HMENU hMenu = GetSystemMenu (hDlg, FALSE);
  78.         ChangeMenu (hMenu, 0, NULL, 0, MF_APPEND);
  79.         ChangeMenu (hMenu, 0, "A&bout Postman...", IDD_ABOUT, MF_APPEND);
  80.         }
  81.  
  82.  
  83.         //  Use a fixed font for the message combobox
  84.  
  85.         SendDlgItemMessage (hDlg, IDD_CB_WMSG, WM_SETFONT,
  86.                               GetStockObject (SYSTEM_FIXED_FONT), 0L);
  87.  
  88.  
  89.         //  limit length of edit controls
  90.  
  91.         for (i=0; i<6; i++)
  92.             SendDlgItemMessage (hDlg,wEditID[i],EM_LIMITTEXT,4,0L);
  93.         SendDlgItemMessage(hDlg,IDD_EDIT_LPARAM,EM_LIMITTEXT,8,0L);
  94.  
  95.  
  96.         //  Subclass the edit controls by substituting filter_hex_number()
  97.         //  for each edit control's windowproc.
  98.         //  Note that the EDIT control's window proc is the same for every one.
  99.  
  100.         lpprocFilterHexNumber = MakeProcInstance ((FARPROC)filter_hex_number, hInstance);
  101.         for (i=0; i<6; i++)
  102.             {
  103.             HWND hWndEdit     = GetDlgItem (hDlg, wEditID[i]);
  104.             lpEditControlProc = (FARPROC) SetWindowLong (hWndEdit, GWL_WNDPROC, (long)lpprocFilterHexNumber);
  105.             }
  106.  
  107.  
  108.         //  Get current number of windows (nWindows)...
  109.         //  and then fill hwnd combobox.
  110.         //
  111.         winlist_enumAll    (hDlg);
  112.         fill_hwnd_combobox (hDlg);
  113.         fill_wmsg_combobox (hDlg);
  114.  
  115.         // EDIT controls are empty...so disable some other controls
  116.         EnableWindow (GetDlgItem(hDlg, IDD_POSTMESSAGE)  , FALSE);
  117.  
  118.         SetDlgItemText (hDlg, IDD_EDIT_HWND  , "");
  119.         SetDlgItemText (hDlg, IDD_EDIT_WMSG  , "");
  120.         SetDlgItemText (hDlg, IDD_EDIT_WPARAM, "");
  121.  
  122.         CheckRadioButton (hDlg,IDD_RB_WM, IDD_RB_USERDEFINED, wFile);
  123.  
  124.         CheckDlgButton (hDlg, IDD_HILO, bHiLo);
  125.         show_lparam_controls (hDlg, bHiLo);
  126.  
  127.         SetFocus (GetDlgItem(hDlg,IDD_CB_HWND) );
  128.         return FALSE;
  129.  
  130.    case WM_MEASUREITEM:
  131.         ((LPMEASUREITEMSTRUCT)lParam)->itemHeight =
  132.              GetSystemMetrics(SM_CYICON) + 8;
  133.         return TRUE;
  134.  
  135.    case WM_DRAWITEM:
  136.         {
  137.         LPDRAWITEMSTRUCT lp = (LPDRAWITEMSTRUCT) lParam ;
  138.  
  139.         if (lp->itemID == -1)
  140.              {
  141.              combobox_DrawFocus (lp);
  142.              }
  143.         else
  144.              {
  145.              switch (lp->itemAction)
  146.                   {
  147.                   case ODA_DRAWENTIRE: combobox_DrawEntireItem (lp); break ;
  148.                   case ODA_SELECT    : combobox_DrawSelection  (lp); break ;
  149.                   case ODA_FOCUS     : combobox_DrawFocus      (lp); break ;
  150.                   }
  151.              }
  152.         }
  153.         return TRUE;
  154.  
  155.    case WM_ERASEBKGND:
  156.         return (IsIconic (hDlg));
  157.  
  158.    case WM_PAINT:
  159.         if (IsIconic(hDlg))
  160.              {
  161.              PAINTSTRUCT ps;
  162.              BeginPaint (hDlg, (LPPAINTSTRUCT) &ps);
  163.              DefWindowProc (hDlg, WM_ICONERASEBKGND, (WORD)ps.hdc, 0L);
  164.              DrawIcon (ps.hdc, 0, 0, LoadIcon (hInstance, "postmanIcon"));
  165.              EndPaint (hDlg, (LPPAINTSTRUCT) &ps);
  166.              return TRUE;
  167.              }
  168.         else
  169.              {
  170.              return FALSE;
  171.              }
  172.  
  173.    case WM_SYSCOMMAND:
  174.         if (wParam == IDD_ABOUT)
  175.              {
  176.              FARPROC lpfnAboutDlgProc = MakeProcInstance (AboutDialogWndProc,hInstance);
  177.              DialogBox (hInstance, MAKEINTRESOURCE (IDD_ABOUT),
  178.                         hDlg, lpfnAboutDlgProc);
  179.              FreeProcInstance (lpfnAboutDlgProc);
  180.              return TRUE;
  181.              }
  182.         else if ((wParam & 0xfff0) == SC_CLOSE)
  183.              {
  184.              //  Restore original Edit Control procs.
  185.              for (i=0; i<=5; i++)
  186.                  {
  187.                  SetWindowLong (GetDlgItem (hDlg, wEditID[i]), GWL_WNDPROC, (long)lpEditControlProc);
  188.                  }
  189.              FreeProcInstance (lpprocFilterHexNumber);
  190.              EndDialog (hDlg, TRUE);
  191.              }
  192.         else
  193.              {
  194.              return FALSE;
  195.              }
  196.  
  197.    case WM_COMMAND:
  198.         switch(wParam)
  199.           {
  200.           case IDD_RB_WM:
  201.           case IDD_RB_USERDEFINED:
  202.           case IDD_RB_REGISTERED:
  203.                if (wParam != wFile)
  204.                    {
  205.                    SendDlgItemMessage (hDlg, wFile, BM_SETCHECK, FALSE, 0L);
  206.                    wFile = wParam;
  207.                    SendDlgItemMessage (hDlg, wFile, BM_SETCHECK, TRUE, 0L);
  208.                    SendDlgItemMessage (hDlg, IDD_CB_WMSG, CB_RESETCONTENT, 0, 0L);
  209.                    fill_wmsg_combobox  (hDlg);
  210.                    }
  211.                return TRUE;
  212.  
  213.           case IDD_REFRESH:
  214.                winlist_enumAll    (hDlg);
  215.                SendDlgItemMessage (hDlg, IDD_CB_HWND, CB_RESETCONTENT, 0, 0L);
  216.                fill_hwnd_combobox (hDlg);
  217.                return TRUE;
  218.  
  219.           case IDD_POSTMESSAGE:
  220.                {
  221.                BOOL bResult;
  222.                char szBuffer[10],
  223.                     szHex[11];
  224.                PSTR pPrefix = "0x";
  225.                HWND hWnd;
  226.                LONG lPar;
  227.                WORD wMsg,
  228.                     wPar,
  229.                     wHi,
  230.                     wLo;
  231.  
  232.                GetDlgItemText (hDlg, IDD_EDIT_HWND, szBuffer, 5);
  233.                strcpy (szHex, pPrefix);
  234.                strcat (szHex, szBuffer);
  235.                hWnd = (HWND) strtol (szHex, NULL, 0);
  236.  
  237.                GetDlgItemText (hDlg, IDD_EDIT_WMSG, szBuffer, 5);
  238.                strcpy(szHex, pPrefix);
  239.                strcat(szHex, szBuffer);
  240.                wMsg = (WORD) strtol (szHex, NULL, 0);
  241.  
  242.                GetDlgItemText (hDlg, IDD_EDIT_WPARAM, szBuffer, 5);
  243.                strcpy (szHex, pPrefix);
  244.                strcat (szHex, szBuffer);
  245.                wPar = (WORD) strtol (szHex, NULL, 0);
  246.  
  247.                if (bHiLo)
  248.                    {
  249.                    GetDlgItemText (hDlg, IDD_EDIT_HIWORD, szBuffer, 5);
  250.                    strcpy (szHex, pPrefix);
  251.                    strcat (szHex, szBuffer);
  252.                    wHi = (WORD) strtol (szHex, NULL, 0);
  253.  
  254.                    GetDlgItemText (hDlg, IDD_EDIT_LOWORD, szBuffer, 5);
  255.                    strcpy (szHex, pPrefix);
  256.                    strcat (szHex, szBuffer);
  257.                    wLo = (WORD) strtol (szHex, NULL, 0);
  258.  
  259.                    lPar = MAKELONG (wLo, wHi);
  260.                    }
  261.                else
  262.                    {
  263.                    GetDlgItemText (hDlg, IDD_EDIT_LPARAM, szBuffer, 9);
  264.                    strcpy (szHex, pPrefix);
  265.                    strcat (szHex, szBuffer);
  266.                    lPar = strtol (szHex, NULL, 0);
  267.                    }
  268.  
  269.                if (!IsWindow (hWnd))
  270.                    MessageBeep (0);
  271.                else
  272.                    {
  273.                    bResult = PostMessage (hWnd, wMsg, wPar, lPar);
  274.                    if (bResult == FALSE)
  275.                        {
  276.                        MessageBeep (0);
  277.                        MessageBox(hDlg, "PostMessage failed.", "PostMessage",(MB_ICONEXCLAMATION | MB_OK));
  278.                        }
  279.                    }
  280.                }
  281.                return TRUE;
  282.  
  283.           case IDD_HILO:
  284.                bHiLo = !bHiLo;
  285.                CheckDlgButton (hDlg, IDD_HILO, bHiLo);
  286.                show_lparam_controls (hDlg, bHiLo);
  287.                return TRUE;
  288.  
  289.  
  290.           case IDD_EDIT_HWND: // activate controls only if all EDIT controls aren't empty.
  291.           case IDD_EDIT_WMSG:
  292.           case IDD_EDIT_WPARAM:
  293.           case IDD_EDIT_LPARAM:
  294.           case IDD_EDIT_HIWORD:
  295.           case IDD_EDIT_LOWORD:
  296.                if ( HIWORD (lParam) == EN_CHANGE )
  297.                    {
  298.                    BOOL bAllFilled;
  299.  
  300.                    if (bHiLo)
  301.                        {
  302.                        bAllFilled =
  303.                            (
  304.                            (BOOL) (SendDlgItemMessage (hDlg, IDD_EDIT_HWND,   WM_GETTEXTLENGTH, 0, 0L)) &&
  305.                            (BOOL) (SendDlgItemMessage (hDlg, IDD_EDIT_WMSG,   WM_GETTEXTLENGTH, 0, 0L)) &&
  306.                            (BOOL) (SendDlgItemMessage (hDlg, IDD_EDIT_WPARAM, WM_GETTEXTLENGTH, 0, 0L)) &&
  307.                            (BOOL) (SendDlgItemMessage (hDlg, IDD_EDIT_HIWORD, WM_GETTEXTLENGTH, 0, 0L)) &&
  308.                            (BOOL) (SendDlgItemMessage (hDlg, IDD_EDIT_LOWORD, WM_GETTEXTLENGTH, 0, 0L))
  309.                            );
  310.                        }
  311.                    else
  312.                        {
  313.                        bAllFilled =
  314.                            (
  315.                            (BOOL) (SendDlgItemMessage (hDlg, IDD_EDIT_HWND,   WM_GETTEXTLENGTH, 0, 0L)) &&
  316.                            (BOOL) (SendDlgItemMessage (hDlg, IDD_EDIT_WMSG,   WM_GETTEXTLENGTH, 0, 0L)) &&
  317.                            (BOOL) (SendDlgItemMessage (hDlg, IDD_EDIT_WPARAM, WM_GETTEXTLENGTH, 0, 0L)) &&
  318.                            (BOOL) (SendDlgItemMessage (hDlg, IDD_EDIT_LPARAM, WM_GETTEXTLENGTH, 0, 0L))
  319.                            );
  320.                        }
  321.                    EnableWindow (GetDlgItem (hDlg, IDD_POSTMESSAGE), bAllFilled);
  322.                    }
  323.                return TRUE;
  324.  
  325.  
  326.           case IDD_CB_HWND:
  327.                /*
  328.                 *   User single clicked or doubled clicked in combobox -
  329.                 *   Fill edit box with selection.
  330.                 */
  331.                if (HIWORD (lParam) == CBN_SELCHANGE)
  332.                   {
  333.                   lResult = SendDlgItemMessage (hDlg,IDD_CB_HWND, CB_GETCURSEL, 0, 0L);
  334.                   if (lResult != CB_ERR)
  335.                       {
  336.                       char szHwnd[5];
  337.                       HWINFO  hWinfo = winlist_getWinfo ();
  338.                       LPWINFO lpWinfo;
  339.  
  340.                       /* retrieve current ListBox selection... */
  341.  
  342.                       lpWinfo = (LPWINFO) GlobalLock (hWinfo);
  343.                       lpWinfo += lResult;
  344.                       wsprintf (szHwnd, "%04X", lpWinfo->hwnd);
  345.                       GlobalUnlock (hWinfo);
  346.  
  347.  
  348.                       /* ...and put in EDIT control.           */
  349.                       SetDlgItemText (hDlg, IDD_EDIT_HWND, szHwnd);
  350.                       }
  351.                   }
  352.                return TRUE;
  353.  
  354.  
  355.           case IDD_CB_WMSG:
  356.                if (HIWORD (lParam) == CBN_SELCHANGE)
  357.                   {
  358.                   lResult  = SendDlgItemMessage(hDlg,IDD_CB_WMSG, CB_GETCURSEL, 0, (LONG)(LPSTR)0);
  359.                   if (lResult != CB_ERR)
  360.                      {
  361.                      char szBuffer [60],
  362.                           szWmsg   [ 5];
  363.  
  364.                      /* retrieve current ListBox selection... */
  365.                      SendDlgItemMessage (hDlg,IDD_CB_WMSG, CB_GETLBTEXT, (WORD)lResult, (LONG)(LPSTR)szBuffer);
  366.  
  367.                      /* ...and put in EDIT control.           */
  368.                      strncpy (szWmsg, szBuffer+29, 4);
  369.                      szWmsg [4] = '\0';
  370.                      SetDlgItemText(hDlg, IDD_EDIT_WMSG, szWmsg);
  371.                      }
  372.                   }
  373.                return TRUE;
  374.  
  375.           default:
  376.                break;
  377.           } /* switch wParam */
  378.  
  379.    default:
  380.         break;
  381.    }
  382.    return FALSE;
  383.    }
  384.  
  385.  
  386.  
  387. static void show_lparam_controls(HWND hDlg, BOOL bHiLo)
  388.     {
  389.     ShowWindow (GetDlgItem (hDlg,IDD_EDIT_LPARAM), bHiLo ? HIDE_WINDOW     : SHOW_OPENWINDOW);
  390.     ShowWindow (GetDlgItem (hDlg,IDD_EDIT_HIWORD), bHiLo ? SHOW_OPENWINDOW : HIDE_WINDOW);
  391.     ShowWindow (GetDlgItem (hDlg,IDD_EDIT_LOWORD), bHiLo ? SHOW_OPENWINDOW : HIDE_WINDOW);
  392.     ShowWindow (GetDlgItem (hDlg,IDD_STEXT_SLASH), bHiLo ? SHOW_OPENWINDOW : HIDE_WINDOW);
  393.  
  394.     SetDlgItemText (hDlg, IDD_EDIT_LPARAM, "");
  395.     SetDlgItemText (hDlg, IDD_EDIT_HIWORD, "");
  396.     SetDlgItemText (hDlg, IDD_EDIT_LOWORD, "");
  397.     }
  398.  
  399.  
  400.  
  401. // filter_hex_number - EDIT Control subclass procedure
  402. //
  403. long FAR PASCAL filter_hex_number(HWND hWnd, unsigned message, WORD wParam, LONG lParam)
  404.     {
  405.     //   Pass on every message we get to the original EDIT control
  406.     //   proc except WM_CHAR.
  407.     //   Only process '0'-'9','A'-'F','a'-'f', and the backspace
  408.     //   character. Ignore other characters.
  409.     //
  410.     if (message == WM_CHAR)
  411.         {
  412.         if (!isxdigit(wParam) && wParam != '\b')
  413.            return 0L;
  414.         else
  415.            return CallWindowProc (lpEditControlProc, hWnd,
  416.                         message, wParam, lParam);
  417.         }
  418.     return CallWindowProc(lpEditControlProc, hWnd, message, wParam, lParam);
  419.     }
  420.  
  421.  
  422. static void check_control_enable(HWND hDlg, int idEdit, int idButton, WORD msg)
  423.     {
  424.     if (msg == EN_CHANGE)
  425.         EnableWindow(GetDlgItem(hDlg, idButton),
  426.            (BOOL)(SendDlgItemMessage(hDlg, idEdit,
  427.            WM_GETTEXTLENGTH, 0, 0L)));
  428.     }
  429.  
  430.  
  431. static void fill_hwnd_combobox (HWND hDlg)
  432.     {
  433.     int n,
  434.         nWindows = winlist_getCount();
  435.  
  436.     for ( n = 1; n <= nWindows; n++)
  437.         {
  438.         SendDlgItemMessage (hDlg, IDD_CB_HWND, CB_ADDSTRING, 0, 0L);
  439.         }
  440.     }
  441.  
  442.  
  443. static void fill_wmsg_combobox (HWND hDlg)
  444.     {
  445.     char szMsgAndHex [35],
  446.          szMsg [81],
  447.          szHex [ 5];
  448.  
  449.     OFSTRUCT ofstruct;
  450.     int      hFile;
  451.     LPSTR    lpFileName;
  452.  
  453.     switch (wFile)
  454.          {
  455.          case IDD_RB_REGISTERED:  lpFileName = "register.msg"; break;
  456.          case IDD_RB_USERDEFINED: lpFileName = "user.msg";     break;
  457.          case IDD_RB_WM:          lpFileName = "wm.msg";
  458.          }
  459.  
  460.      hFile = OpenFile (lpFileName, &ofstruct, OF_READ);
  461.  
  462.      if (hFile != -1)
  463.           {
  464.           FILE *fp = fdopen(hFile, "r");
  465.           szMsgAndHex [34] = '\0';
  466.  
  467.           if (wFile == IDD_RB_REGISTERED)
  468.                {
  469.                while (fscanf(fp,"%80s", szMsg) != EOF)
  470.                    {
  471.                    wsprintf(szMsgAndHex,"%-28.28s %X", (LPSTR)szMsg, RegisterWindowMessage(szMsg));
  472.                    SendDlgItemMessage (hDlg, IDD_CB_WMSG, CB_ADDSTRING, 0, (long)(LPSTR)szMsgAndHex);
  473.                    }
  474.                }
  475.           else
  476.                {
  477.                while (fscanf(fp,"%80s %4s", szMsg, szHex) != EOF )
  478.                    {
  479.                    wsprintf(szMsgAndHex,"%-28.28s %s", (LPSTR)szMsg, (LPSTR)szHex);
  480.                    SendDlgItemMessage (hDlg, IDD_CB_WMSG, CB_ADDSTRING, 0, (long)(LPSTR)szMsgAndHex);
  481.                    }
  482.                }
  483.           fclose (fp);
  484.           }
  485.     }
  486.  
  487.  
  488. static void combobox_DrawEntireItem (LPDRAWITEMSTRUCT lp)
  489.      {
  490.      char  szBuffer[70];
  491.      LPSTR lpTypeName;
  492.      int    nCount ,
  493.             nIndent1,
  494.             nIndent2,
  495.             nIconWidth = GetSystemMetrics (SM_CXICON);
  496.      HWINFO  hWinfo    = winlist_getWinfo ();
  497.      LPWINFO lpWinfo;
  498.      HICON  hIcon;
  499.      RECT   rc;
  500.  
  501.      lpWinfo = (LPWINFO) GlobalLock (hWinfo);
  502.      lpWinfo += lp->itemID;
  503.  
  504.      nIndent1 = lpWinfo->nLevel * nIconWidth + 10;
  505.      nIndent2 = nIndent1 + nIconWidth + 5;
  506.  
  507.      if (!IsWindow (lpWinfo->hwnd))
  508.           hIcon = LoadIcon (hInstance, "invalidIcon");
  509.      else if (lpWinfo->hIcon)
  510.           hIcon = lpWinfo->hIcon;
  511.      else
  512.           hIcon = LoadIcon (hInstance, "nullIcon");
  513.  
  514.      DrawIcon (lp->hDC, lp->rcItem.left+nIndent1, lp->rcItem.top+4, hIcon) ;
  515.  
  516.      if (lpWinfo->dwStyle & WS_CHILD)       lpTypeName = "Child";
  517.      else if( lpWinfo->dwStyle & WS_ICONIC) lpTypeName = "Icon";
  518.      else if( lpWinfo->dwStyle & WS_POPUP ) lpTypeName = "Popup";
  519.      else                                   lpTypeName = "Overlapped";
  520.  
  521.      wsprintf(szBuffer,"%s %04X %04X [%.14s] \"%.30s\"",
  522.              lpTypeName,
  523.              lpWinfo->hwnd,
  524.              lpWinfo->hwndParent,
  525.              (LPSTR)(lpWinfo->szClassName),
  526.              (LPSTR)(lpWinfo->szTitle));
  527.  
  528.      nCount  = _fstrlen (szBuffer) ;
  529.      rc      = lp->rcItem;
  530.      rc.left = lp->rcItem.left + nIndent2;
  531.      rc.top  = lp->rcItem.top  + 8;
  532.  
  533.      if (lpWinfo->bColor && GetBkColor(lp->hDC) == RGB(255,255,255))
  534.           {
  535.           COLORREF crOld = SetTextColor (lp->hDC, RGB (0,0,255));
  536.           DrawText (lp->hDC, szBuffer, nCount, &rc, DT_SINGLELINE) ;
  537.           SetTextColor (lp->hDC, crOld);
  538.           }
  539.      else
  540.           {
  541.           DrawText (lp->hDC, szBuffer, nCount, &rc, DT_SINGLELINE) ;
  542.           }
  543.  
  544.      combobox_DrawFocus     (lp);
  545.      combobox_DrawSelection (lp);
  546.      GlobalUnlock (hWinfo);
  547.      }
  548.  
  549.  
  550. static void combobox_DrawFocus (LPDRAWITEMSTRUCT lp)
  551.      {
  552.      HBRUSH hbr;
  553.      RECT   rc ;
  554.  
  555.      CopyRect (&rc, &lp->rcItem);
  556.      InflateRect (&rc, -3, -3);
  557.  
  558.      if (lp->itemState & ODS_FOCUS)
  559.           {
  560.           hbr = GetStockObject (GRAY_BRUSH);
  561.           }
  562.      else
  563.           {
  564.           hbr = CreateSolidBrush (GetSysColor(COLOR_WINDOW)) ;
  565.           }
  566.      FrameRect (lp->hDC, &rc, hbr);
  567.      DeleteObject (hbr);
  568.      }
  569.  
  570.  
  571. static void combobox_DrawSelection (LPDRAWITEMSTRUCT lp)
  572.      {
  573.      HBRUSH hbr;
  574.      RECT   rc ;
  575.  
  576.      CopyRect (&rc, &lp->rcItem);
  577.      InflateRect (&rc, -1, -1);
  578.  
  579.      if (lp->itemState & ODS_SELECTED)
  580.           {
  581.           hbr = GetStockObject (BLACK_BRUSH);
  582.           }
  583.      else
  584.           {
  585.           hbr = CreateSolidBrush (GetSysColor(COLOR_WINDOW)) ;
  586.           }
  587.      FrameRect (lp->hDC, &rc, hbr);
  588.      DeleteObject (hbr);
  589.      }
  590.  
  591.  
  592. BOOL FAR PASCAL AboutDialogWndProc (HWND hDlg, unsigned m, WORD w, LONG l)
  593.      {
  594.      switch (m)
  595.           {
  596.           case WM_INITDIALOG:
  597.                return TRUE;
  598.  
  599.           case WM_COMMAND:
  600.                EndDialog (hDlg, 0);
  601.                return TRUE;
  602.           }
  603.      return FALSE;
  604.      }
  605.